import Singleton from "../Base/Singleton";

interface IEvent {
    func: Function,
    ctx: unknown
}

export default class EventManager extends Singleton {

    static get Instance() {
        return super.getInstance<EventManager>();
    }

    private _eventDic: Map<string, Array<IEvent>> = new Map();

    on(eventName: string, func: Function, ctx: unknown) {
        if (this._eventDic.has(eventName)) {
            this._eventDic.get(eventName).push({ func, ctx });
        } else {
            this._eventDic.set(eventName, [{ func, ctx }]);
        }
    }

    off(eventName: string, func: Function, ctx: unknown) {
        if (this._eventDic.has(eventName)) {
            const index = this._eventDic.get(eventName).findIndex(event => event.func === func && event.ctx === ctx);
            index > -1 && this._eventDic.get(eventName).splice(index, 1)
        }
    }

    emit(eventName: string, ...args: unknown[]) {
        if (this._eventDic.has(eventName)) {
            this._eventDic.get(eventName).forEach(({ func, ctx }) => {
                ctx ? func.apply(ctx, ...args) : func(...args);
            })
        }
    }

    clear() {
        this._eventDic.clear();
    }
}
